package cn.uncode.baas.server.internal.module.mail;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import cn.uncode.dal.internal.util.message.Messages;
import cn.uncode.baas.server.exception.ValidateException;
import cn.uncode.baas.server.utils.DataUtils;
import org.springframework.stereotype.Service;



@Service
public class MailModule implements IMailModule {
	
	private static Log LOG = LogFactory.getLog(MailModule.class);

    @Override
    public boolean sendMail(Object param) throws ValidateException {
        Map<String, Object> map = DataUtils.convert2Map(param);
        map.put("port", map.get("port").toString().split("\\.")[0]);
        Mail mail = Mail.valueOf(map);
        if (mail.getType() == 3) {
            throw new ValidateException(Messages.getString("ValidateError.17"));
        }
        if(map.containsKey("type")){
        	String type = String.valueOf(map.get("type"));
        	if(StringUtils.isNotEmpty(type) && "sync".equals(type)){
        		if (mail.getType() == 2) {
                    return sendHtmlMail(mail);
                } else if (mail.getType() == 1) {
                    return sendTextMail(mail);
                }
        	}
        }
        Timer timer = new Timer();
        timer.schedule(new EmailTask(mail), 0, 1000);
        return true;
    }

    /**
     * 以文本格式发送邮件
     * 
     * @param mailInfo 待发送的邮件的信息
     * @return result
     */
    public static boolean sendTextMail(Mail mailInfo) {

        // 判断是否需要身份认证
        MailAuthenticator authenticator = null;
        Properties properties = mailInfo.getProperties();
        if (mailInfo.isValidate()) {
            // 如果需要身份认证，则创建一个密码验证器
            authenticator = new MailAuthenticator(mailInfo.getUsername(), mailInfo.getPassword());
        }

        // 根据邮件会话属性和密码验证器构造一个发送邮件的session
        Session sendMailSession = Session.getDefaultInstance(properties, authenticator);
        try {
            Message mailMessage = new MimeMessage(sendMailSession);// 根据session创建一个邮件消息
            Address from = new InternetAddress(mailInfo.getFromAddress());// 创建邮件发送者地址
            mailMessage.setFrom(from);// 设置邮件消息的发送者
            // 创建邮件的接收者地址
            List<String> toAddress = null;
            if (mailInfo.getToAddress().size() > 1) {
                toAddress = mailInfo.getToAddress();
                Address[] address = new InternetAddress[toAddress.size()];
                for (int i = 0; i < toAddress.size(); i++) {
                    address[i] = new InternetAddress(toAddress.get(i));
                }
                mailMessage.setRecipients(Message.RecipientType.TO, address);// 设置邮件消息的接收者
            } else {
                toAddress = mailInfo.getToAddress();
                Address to = new InternetAddress(toAddress.get(0));
                // Message.RecipientType.TO属性表示接收者的类型为TO
                mailMessage.setRecipient(Message.RecipientType.TO, to);// 设置邮件消息的接收者
            }
            mailMessage.setSubject(mailInfo.getSubject());// 设置邮件消息的主题
            // mailMessage.setSentDate(new Date());// 设置邮件消息发送的时间
            // mailMessage.setText(mailInfo.getContent());//设置邮件消息的主要内容

            // MimeMultipart类是一个容器类，包含MimeBodyPart类型的对象
            Multipart mainPart = new MimeMultipart();
            MimeBodyPart messageBodyPart = new MimeBodyPart();// 创建一个包含附件内容的MimeBodyPart
            // 设置HTML内容
            messageBodyPart.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
            mainPart.addBodyPart(messageBodyPart);

            // 存在附件
            String[] filePaths = mailInfo.getAttachFileNames();
            if (filePaths != null && filePaths.length > 0) {
                for (String filePath : filePaths) {
                    messageBodyPart = new MimeBodyPart();
                    File file = new File(filePath);
                    if (file.exists()) {// 附件存在磁盘中
                        FileDataSource fds = new FileDataSource(file);// 得到数据源
                        messageBodyPart.setDataHandler(new DataHandler(fds));// 得到附件本身并至入BodyPart
                        messageBodyPart.setFileName(file.getName());// 得到文件名同样至入BodyPart
                        mainPart.addBodyPart(messageBodyPart);
                    }
                }
            }

            // 将MimeMultipart对象设置为邮件内容
            mailMessage.setContent(mainPart);
            Transport.send(mailMessage);// 发送邮件
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 以HTML格式发送邮件
     * 
     * @param mailInfo
     *            待发送的邮件信息
     * @return
     */
    public static boolean sendHtmlMail(Mail mailInfo) {

        // 判断是否需要身份认证
        MailAuthenticator authenticator = null;
        Properties properties = mailInfo.getProperties();
        if (mailInfo.isValidate()) {
            // 如果需要身份认证，则创建一个密码验证器
            authenticator = new MailAuthenticator(mailInfo.getUsername(), mailInfo.getPassword());
        }

        // 根据邮件会话属性和密码验证器构造一个发送邮件的session
        Session sendMailSession = Session.getDefaultInstance(properties, authenticator);
        try {
            Message mailMessage = new MimeMessage(sendMailSession);// 根据session创建一个邮件消息
            Address from = new InternetAddress(mailInfo.getFromAddress());// 创建邮件发送者地址
            mailMessage.setFrom(from);// 设置邮件消息的发送者
            // Address to = new InternetAddress(mailInfo.getToAddress());
            // 创建邮件的接收者地址
            List<String> toAddress = null;
            if (mailInfo.getToAddress().size() > 1) {
                toAddress = mailInfo.getToAddress();
                Address[] address = new InternetAddress[toAddress.size()];
                for (int i = 0; i < toAddress.size(); i++) {
                    address[i] = new InternetAddress(toAddress.get(i));
                }
                mailMessage.setRecipients(Message.RecipientType.TO, address);// 设置邮件消息的接收者
            } else {
                toAddress = mailInfo.getToAddress();
                Address to = new InternetAddress(toAddress.get(0));
                // Message.RecipientType.TO属性表示接收者的类型为TO
                mailMessage.setRecipient(Message.RecipientType.TO, to);// 设置邮件消息的接收者
            }
            mailMessage.setSubject(mailInfo.getSubject());// 设置邮件消息的主题
            // mailMessage.setSentDate(new Date());// 设置邮件消息发送的时间
            // MimeMultipart类是一个容器类，包含MimeBodyPart类型的对象
            Multipart mainPart = new MimeMultipart();
            MimeBodyPart messageBodyPart = new MimeBodyPart();// 创建一个包含HTML内容的MimeBodyPart
            // 设置HTML内容
            messageBodyPart.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
            mainPart.addBodyPart(messageBodyPart);

            // 存在附件
            String[] filePaths = mailInfo.getAttachFileNames();
            if (filePaths != null && filePaths.length > 0) {
                for (String filePath : filePaths) {
                    messageBodyPart = new MimeBodyPart();
                    File file = new File(filePath);
                    if (file.exists()) {// 附件存在磁盘中
                        FileDataSource fds = new FileDataSource(file);// 得到数据源
                        messageBodyPart.setDataHandler(new DataHandler(fds));// 得到附件本身并至入BodyPart
                        messageBodyPart.setFileName(file.getName());// 得到文件名同样至入BodyPart
                        mainPart.addBodyPart(messageBodyPart);
                    }
                }
            }

            // 将MimeMultipart对象设置为邮件内容
            mailMessage.setContent(mainPart);
            Transport.send(mailMessage);// 发送邮件
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    
    
    /**
     * task runnable.
     */
    private static class EmailTask extends TimerTask {

        private int time = 1;
        
        private Mail mail;

        /**
         * @param userInfoService
         */
        public EmailTask(final Mail mailInfo) {
            this.mail = mailInfo;
        }

        public void run() {
            if (time > 0) {
                try {
                	if (mail.getType() == 2) {
                        sendHtmlMail(mail);
                    } else if (mail.getType() == 1) {
                        sendTextMail(mail);
                    }
                    time--;
                    LOG.debug("EmailTask run times:" + time);
                } catch (Exception e) {
                    LOG.error(e);
                } finally {
                }
            } else {
                this.cancel();
            }
        }
    }

}
